package com.zmn.plat.business.impl.channel;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.mcc.cas.model.LoginStaff;
import com.zmn.mcc.cas.web.StaffAdminService;
import com.zmn.plat.business.interfaces.channel.ChannelProductMapBService;
import com.zmn.plat.common.dictionary.PlatErrorCodeDict;
import com.zmn.plat.common.dto.channel.ChannelProductMapDRO;
import com.zmn.plat.common.dto.product.ServProductDRO;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.manager.dictionary.ChannelDict;
import com.zmn.plat.model.entity.channel.Channel;
import com.zmn.plat.model.entity.channel.product.map.ChannelProductMap;
import com.zmn.plat.model.entity.channel.product.map.ChannelProductMapQuery;
import com.zmn.plat.model.entity.product.ServProduct;
import com.zmn.plat.services.interfaces.channel.ChannelService;
import com.zmn.plat.services.interfaces.channel.product.map.ChannelProductMapService;
import com.zmn.plat.services.interfaces.product.ServProductService;
import org.apache.commons.collections.ListUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import lombok.extern.log4j.Log4j2;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Log4j2
public class ChannelProductMapBServiceImpl implements ChannelProductMapBService {

    @Resource
    private ChannelProductMapService channelProductMapService;

    @Resource
    private ChannelService channelService;

    @Resource
    private ServProductService servProductService;

    private final Integer MAX_MAP_NUM = 50;

    @Override
    @SuppressWarnings("Duplicates")
    public List<ChannelProductMapDRO> listByChannelIdAndProductId(Integer channelId, Integer productId) {
        if (NumberUtil.isNullOrZero(channelId) || NumberUtil.isNullOrZero(productId)) {
            log.error("listByChannelIdAndProductId参数不能为空：channelId：{}，productId：{}", channelId, productId);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
        }

        ChannelProductMapQuery query = new ChannelProductMapQuery();
        query.setChannelId(channelId);
        query.setProductId(productId);
        query.setStatus(GlobalConsts.YES);
        List<ChannelProductMap> channelProductMaps = channelProductMapService.listByQuery(query);

        // 如果二级渠道没有有效数据则继承一级渠道的数据
        if (CollectionUtil.isNullOrEmpty(channelProductMaps)) {
            Channel channel = Optional.ofNullable(channelService.findByKey(channelId)).orElse(new Channel());
            if (Objects.equals(channel.getRank(), ChannelDict.RANK_TWO) && NumberUtil.isPositiveInteger(channel.getParentId())) {
                query.setChannelId(channel.getParentId());
                channelProductMaps = channelProductMapService.listByQuery(query);
            }
        }

        List<ChannelProductMapDRO> result = Lists.newArrayListWithExpectedSize(channelProductMaps.size());
        channelProductMaps.forEach(e -> {
            ChannelProductMapDRO channelProductMapDRO = new ChannelProductMapDRO();
            channelProductMapDRO.setChannelId(e.getChannelId());
            channelProductMapDRO.setProductId(e.getProductId());
            channelProductMapDRO.setChannelProductParentId(e.getChannelProductParentId());
            String channelProductSubId = e.getChannelProductSubId();
            if (StringUtil.isNotBlank(channelProductSubId)) {
                List<String> subIds = convertStrsToList(channelProductSubId);
                channelProductMapDRO.setChannelProductSubIds(subIds);
            } else {
                channelProductMapDRO.setChannelProductSubIds(Collections.emptyList());
            }

            result.add(channelProductMapDRO);
        });

        return result;
    }

    @Override
    @SuppressWarnings("Duplicates")
    public List<ServProductDRO> listByChannelIdAndProductParentIdAndProductSubId(Integer channelId, String channeProductParentId, String channeProductSubId) {
        if (NumberUtil.isNullOrZero(channelId)) {
            log.error("listByChannelIdAndProductId 渠道ID参数不能为空：channelId：{}，channeProductParentId：{}，channeProductSubId：{}", channelId, channeProductParentId, channeProductSubId);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
        }

        ChannelProductMapQuery query = new ChannelProductMapQuery();
        query.setChannelId(channelId);
        query.setChannelProductParentId(channeProductParentId);
        query.setChannelProductSubId(channeProductSubId);
        query.setStatus(GlobalConsts.YES);
        List<ChannelProductMap> channelProductMaps = channelProductMapService.listByQuery(query);

        // 如果二级渠道没有有效数据则继承一级渠道的数据
        if (CollectionUtil.isNullOrEmpty(channelProductMaps)) {
            Channel channel = Optional.ofNullable(channelService.findByKey(channelId)).orElse(new Channel());
            if (Objects.equals(channel.getRank(), ChannelDict.RANK_TWO) && NumberUtil.isPositiveInteger(channel.getParentId())) {
                query.setChannelId(channel.getParentId());
                channelProductMaps = channelProductMapService.listByQuery(query);
            }
        }

        if (CollectionUtil.isNotNullOrEmpty(channelProductMaps)) {
            List<Integer> productIds = channelProductMaps.stream().map(e -> e.getProductId()).distinct().collect(Collectors.toList());
            List<ServProduct> servProducts = servProductService.listByIdList(productIds);

            List<ServProductDRO> result = servProducts.stream().map(servProduct -> {
                ServProductDRO servProductDRO = new ServProductDRO();
                BeanUtils.copyProperties(servProduct, servProductDRO);
                return servProductDRO;
            }).collect(Collectors.toList());

            return result;
        } else {
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEditChannelProductMap(Integer channelId, Integer productId, Integer relateId, String channelProductParentId, String channelProductSubId) {
        // 主键ID为0或者空时，代表新增，否则为修改
        if (NumberUtil.isNullOrZero(relateId)) {
            addChannelProductMap(channelId, productId, relateId, channelProductParentId, channelProductSubId);
        } else {
            modifyChannelProductMap(channelId, productId, relateId, channelProductParentId, channelProductSubId);
        }
    }

    private void addChannelProductMap(Integer channelId, Integer productId, Integer relateId, String channelProductParentId, String channelProductSubId) {

        // 唯一性校验
        checkUnique(channelId, productId, channelProductParentId, channelProductSubId);

        ChannelProductMapQuery query = new ChannelProductMapQuery();
        query.setChannelId(channelId);
        query.setProductId(productId);
        query.setChannelProductParentId(channelProductParentId);
        List<ChannelProductMap> result = channelProductMapService.listByQuery(query);

        String operator = getDeptUnionOperator();

        if (CollectionUtil.isNotNullOrEmpty(result)) {
            // 当新增“渠道方产品父ID”相同时，子ID不同，自动合并到“相同父ID下，对应的子ID”
            ChannelProductMap oldChannelProductMap = result.get(0);
            String oldProductSubId = oldChannelProductMap.getChannelProductSubId();
            List<String> oldProductSubIds = convertStrsToList(oldProductSubId);
            List<String> newProductSubIds = convertStrsToList(channelProductSubId);
            List<Integer> mergeSubIdList = ListUtils.sum(oldProductSubIds, newProductSubIds);
            String mergeSubIds = Joiner.on(",").join(mergeSubIdList);
            oldChannelProductMap.setChannelProductSubId(mergeSubIds);
            oldChannelProductMap.setUpdater(operator);
            oldChannelProductMap.setUpdateTime(new Date());

            channelProductMapService.updateByKey(oldChannelProductMap);
        } else {
            query.setChannelProductParentId(null);
            List<ChannelProductMap> all = channelProductMapService.listByQuery(query);
            if (CollectionUtil.isNotNullOrEmpty(all) && all.size() >= MAX_MAP_NUM) {
                throw new PlatException("渠道产品映射最多50组，请修改后再试！");
            }

            ChannelProductMap insertData = new ChannelProductMap();
            insertData.setChannelId(channelId);
            insertData.setProductId(productId);
            insertData.setChannelProductParentId(channelProductParentId);
            insertData.setChannelProductSubId(channelProductSubId);
            insertData.setStatus(GlobalConsts.YES);
            insertData.setCreater(operator);
            insertData.setCreateTime(new Date());
            insertData.setUpdater(operator);
            insertData.setUpdateTime(new Date());
            channelProductMapService.insert(insertData);
        }
    }

    private void modifyChannelProductMap(Integer channelId, Integer productId, Integer relateId, String channelProductParentId, String channelProductSubId) {
        // 修改渠道映射关系父ID/子ID=删除原父ID/子ID+新增现父ID/子ID
        channelProductMapService.deleteByKey(relateId);

        addChannelProductMap(channelId, productId, relateId, channelProductParentId, channelProductSubId);
    }

    private void checkUnique(Integer channelId, Integer productId, String channelProductParentId, String channelProductSubId) {
        ChannelProductMapQuery query = new ChannelProductMapQuery();
        query.setChannelId(channelId);
        query.setChannelProductParentId(channelProductParentId);
        query.setStatus(GlobalConsts.YES);
        List<ChannelProductMap> result = channelProductMapService.listByQuery(query);

        if (StringUtil.isBlank(channelProductSubId)) {
            List<ChannelProductMap> filterResult = result.stream().filter(e -> StringUtil.isBlank(e.getChannelProductSubId())).filter(e -> !Objects.equals(e.getProductId(), productId)).collect(Collectors.toList());
            if (CollectionUtil.isNotNullOrEmpty(filterResult)) {
                ServProduct servProduct = servProductService.findByKey(filterResult.get(0).getProductId());
                StringBuffer sb = new StringBuffer();
                sb.append("渠道父产品ID").append(channelProductParentId).append("映射关系与").
                        append(servProduct.getName()).append("相同，请核实渠道产品信息");
                throw new PlatException(sb.toString());
            }
        } else {
            List<ChannelProductMap> filterResult = result.stream().filter(e -> StringUtil.isNotBlank(e.getChannelProductSubId())).filter(e -> !Objects.equals(e.getProductId(), productId)).collect(Collectors.toList());

            List<String> currentChannelProductSubIds = convertStrsToList(channelProductSubId);
            for (int i = 0; i < filterResult.size(); i++) {
                ChannelProductMap innnerChannelProductMap = filterResult.get(i);
                List<String> innerChannelProductSubIds = convertStrsToList(innnerChannelProductMap.getChannelProductSubId());

                // 如果渠道方子产品ID有交集 则不允许新增
                innerChannelProductSubIds.retainAll(currentChannelProductSubIds);

                if (CollectionUtil.isNotNullOrEmpty(innerChannelProductSubIds)) {
                    ServProduct servProduct = servProductService.findByKey(filterResult.get(i).getProductId());
                    StringBuffer sb = new StringBuffer();
                    sb.append("渠道父产品ID").append(channelProductParentId).append("，").append("渠道子产品ID").
                            append(channelProductSubId).append("映射关系与").append(servProduct.getName()).append("相同，请核实渠道产品信息");
                    throw new PlatException(sb.toString());
                }
            }
        }
    }

    /**
     * 拼接操作员的部门信息和姓名
     * 
     * @return
     */
    private String getDeptUnionOperator() {
        String operator = "";
        try {
            LoginStaff loginStaff = StaffAdminService.currentStaff();
            operator = loginStaff.getDeptName() + "-" + loginStaff.getRealName();
        } catch (Exception e) {
            log.error("createLog getStaff is error! defaultStaff: SYSTEM");
            operator = "SYSTEM";
        }

        return operator;
    }

    private List<String> convertStrsToList(String strs) {
        List<String> ids = new ArrayList();
        if (StringUtil.isBlank(strs.trim())) {
            return ids;
        } else {
            String[] tmpIds = strs.split(",");
            String[] var3 = tmpIds;
            int var4 = tmpIds.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                String tmpId = var3[var5];
                if (!StringUtil.isBlank(tmpId.trim())) {
                    ids.add(tmpId.trim());
                }
            }

            return ids;
        }
    }

}
